#include <stdio.h>

#include "proteindata.h"

using namespace PBVP;

ProteinData::ProteinData()
{
	
}

ProteinData::~ProteinData()
{
	for (int i = 0; i < m_ChainList.size(); i++) {
		delete m_ChainList[i];
	}
	for (int i = 0; i < m_LigandList.size(); i++) {
		delete m_LigandList[i];
	}
}

QVector<Atom> ProteinData::getAtoms() 
{
	QVector<Atom> atomList;
	
	// do not include HET atom in the list
	for (int i = 0; i < numOfChains(); i++)
	{
		QVector<Atom> chainAtoms(m_ChainList[i]->getAtoms());
		for(int j = 0; j < chainAtoms.size(); j++) {
			atomList.append(chainAtoms[j]);
		}
		
	}
	return atomList;
}

void ProteinData::setMetaData(const PBVP::ProteinMetaData &meta)
{
	m_MetaData = meta;
}

ChainData* ProteinData::addChain(char id)
{
	// new chain is added when residue sequences are parsed
	ChainData* pChain = new ChainData(id, this);

	// set the index of the first residue for the chain
	// pChain->setFirstResidue(m_Residues.size());
	m_ChainList.push_back(pChain);
	
	return pChain;
}

ChainData* ProteinData::getChain(char id)
{
	for(int i = 0; i < m_ChainList.size(); i++) {
		if(m_ChainList[i]->id() == id) return m_ChainList[i];
	}
	// should not come here
	assert(0);
	return NULL;
}

ChainData* ProteinData::getChain(int i) {
	return m_ChainList[i];
}

LigandData* ProteinData::addLigand(const QString &name)
{
	// Ligands are added when parsing HETATM
	LigandData *pLigand = new LigandData(name, this);

	// set the index of the first ligand atom
	// pLigand->setFirstAtom(m_Atoms.size());
	m_LigandList.append(pLigand);

	return pLigand;
}

LigandData* ProteinData::getLigand(const QString& name)
{
	for(int i = 0; i < m_LigandList.size(); i++) {
		if(m_LigandList[i]->name() == name) {
			return m_LigandList[i];
		}
	}
	return NULL;
}

LigandData* ProteinData::getLigand(int i)
{
	assert(i < m_LigandList.size());
	return m_LigandList[i];
}

void ProteinData::print() const
{
	printf("PDB ID: %s\n", m_MetaData.ID.toAscii().data());
	printf("Number of chains: %d\n", numOfChains());
	for(int i = 0; i < numOfChains(); i++) {
		m_ChainList[i]->print();
	}
	printf("Number of ligands: %d\n", numOfLigands());
	for(int i = 0; i < numOfLigands(); i++) {
		m_LigandList[i]->print();
	}
	printf("Total number of residues: %d\n", numOfResidues());
	printf("Total number of atoms: %d\n", numOfAtoms());
}

QStringList ProteinData::getChainNames() const
{
	QStringList names;
	for(int i = 0; i < numOfChains(); i++) {
		names.append(QString(m_ChainList[i]->id()));
	}
	return names;
}

QStringList ProteinData::getLigandNames() const
{
	QStringList names;
	for(int i = 0; i < numOfLigands(); i++) {
		names.append(m_LigandList[i]->name());
	}
	return names;
}